﻿using System.Collections.Concurrent;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace cap01.Common.Rabbitmq;

public class MQClients
{
    /// <summary>
    /// 广播消息模式
    /// </summary>
    [MQueue("huasky.FanoutNotify")]
	public static MQFanoutClient<string> FanoutNotify => GetClient<MQFanoutClient<string>>();

	/// <summary>
	/// 生产消费模式
	/// </summary>
	[MQueue("huasky.simple")]
	public static MQLiteClient<string> SimpleNotify => MqueueClient<string>();


    static ConcurrentDictionary<string, Lazy<object>> _lazyClients = new();
	static MQClients()
	{
		Init();
	}

	static void Init()
	{
		//mq消息队列采用lazy的形式 （各模块只使用部分队列）
		var properties = typeof(MQClients).GetProperties();

		foreach (var property in properties)
		{
			var attr = property.GetCustomAttribute<MQueueAttribute>();
			_lazyClients[property.Name] = new Lazy<object>(() =>
			{
				var queueName = attr.Name;
				return Activator.CreateInstance(property.PropertyType, queueName);
			}, true);
		}
	}

	/// <summary>
	/// 获取消息队列（直连交换机）
	/// </summary>
	static MQLiteClient<T> MqueueClient<T>([CallerMemberName] string property = null)
	{
		return _lazyClients[property].Value as MQLiteClient<T>;
	}

	/// <summary>
	/// 获取消息队列（扇形交换机）
	/// </summary>
	static T GetClient<T>([CallerMemberName] string property = null) where T: class
    {
        return _lazyClients[property].Value as T;
    }


    [AttributeUsage(AttributeTargets.Property)]
	class MQueueAttribute : Attribute
	{
		public string Name { get; set; }
		
		public MQueueAttribute(string name)
		{
			this.Name = name;
		}
	}
}